From 4a6a894fa3016fbd005ee088a06d634e7424dd99 Mon Sep 17 00:00:00 2001 From: parkrrrr Date: Tue, 14 Sep 2004 19:13:56 +0000 Subject: [PATCH] Added stack filter, exit routines for filters --- gpsbabel/Makefile | 13 ++- gpsbabel/arcdist.c | 1 + gpsbabel/defs.h | 3 + gpsbabel/duplicate.c | 1 + gpsbabel/filter_vecs.c | 19 +++++ gpsbabel/main.c | 1 + gpsbabel/polygon.c | 1 + gpsbabel/position.c | 2 + gpsbabel/queue.h | 6 ++ gpsbabel/reverse_route.c | 1 + gpsbabel/smplrout.c | 1 + gpsbabel/sort.c | 1 + gpsbabel/stackfilter.c | 177 +++++++++++++++++++++++++++++++++++++++ 13 files changed, 225 insertions(+), 2 deletions(-) create mode 100644 gpsbabel/stackfilter.c diff --git a/gpsbabel/Makefile b/gpsbabel/Makefile index 198762148..e9dfb8fca 100644 --- a/gpsbabel/Makefile +++ b/gpsbabel/Makefile @@ -22,7 +22,7 @@ FMTS=magproto.o gpx.o geo.o mapsend.o mapsource.o garmin_tables.o \ ozi.o nmea.o text.o html.o palmdoc.o netstumbler.o hsa_ndv.o \ igc.o brauniger_iq.o -FILTERS=position.o duplicate.o arcdist.o polygon.o smplrout.o reverse_route.o sort.o +FILTERS=position.o duplicate.o arcdist.o polygon.o smplrout.o reverse_route.o sort.o stackfilter.o JEEPS=jeeps/gpsapp.o jeeps/gpscom.o \ jeeps/gpsmath.o jeeps/gpsmem.o \ @@ -110,6 +110,12 @@ mac-release: # Machine generated from here down. arcdist.o: arcdist.c defs.h queue.h grtcirc.h +brauniger_iq.o: brauniger_iq.c defs.h queue.h jeeps/gpsserial.h \ + jeeps/gps.h jeeps/gpsport.h jeeps/gpssend.h jeeps/gpsread.h \ + jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ + jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h \ + jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h \ + jeeps/gpsnmeaget.h cetus.o: cetus.c defs.h queue.h coldsync/palm.h coldsync/pdb.h copilot.o: copilot.c defs.h queue.h coldsync/palm.h coldsync/pdb.h csv_util.o: csv_util.c defs.h queue.h csv_util.h grtcirc.h @@ -140,6 +146,7 @@ html.o: html.c defs.h queue.h jeeps/gpsmath.h jeeps/gps.h jeeps/gpsport.h \ jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h jeeps/gpsinput.h \ jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h +igc.o: igc.c defs.h queue.h internal_styles.o: internal_styles.c defs.h queue.h magnav.o: magnav.c defs.h queue.h coldsync/palm.h coldsync/pdb.h magproto.o: magproto.c defs.h queue.h magellan.h @@ -170,6 +177,7 @@ route.o: route.c defs.h queue.h saroute.o: saroute.c defs.h queue.h smplrout.o: smplrout.c defs.h queue.h grtcirc.h sort.o: sort.c defs.h queue.h +stackfilter.o: stackfilter.c defs.h queue.h text.o: text.c defs.h queue.h jeeps/gpsmath.h jeeps/gps.h jeeps/gpsport.h \ jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ @@ -212,7 +220,8 @@ jeeps/gpsmem.o: jeeps/gpsmem.c jeeps/gps.h defs.h queue.h jeeps/gpsport.h \ jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \ jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \ jeeps/gpsmath.h jeeps/gpsnmea.h jeeps/gpsmem.h jeeps/gpsrqst.h \ - jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h + jeeps/gpsinput.h jeeps/gpsproj.h jeeps/gpsnmeafmt.h jeeps/gpsnmeaget.h \ + jeeps/garminusb.h jeeps/gpsprot.o: jeeps/gpsprot.c jeeps/gps.h defs.h queue.h \ jeeps/gpsport.h jeeps/gpsserial.h jeeps/gpssend.h jeeps/gpsread.h \ jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h \ diff --git a/gpsbabel/arcdist.c b/gpsbabel/arcdist.c index 1f5f1d2f1..7f49dffc6 100644 --- a/gpsbabel/arcdist.c +++ b/gpsbabel/arcdist.c @@ -159,5 +159,6 @@ filter_vecs_t arcdist_vecs = { arcdist_init, arcdist_process, arcdist_deinit, + NULL, arcdist_args }; diff --git a/gpsbabel/defs.h b/gpsbabel/defs.h index 7da7c4156..c59e1f1bb 100644 --- a/gpsbabel/defs.h +++ b/gpsbabel/defs.h @@ -246,6 +246,7 @@ char *GET_OPTION(const char *iarglist, const char *argname, DEBUG_PARAMS); typedef void (*filter_init) (char const *); typedef void (*filter_process) (void); typedef void (*filter_deinit) (void); +typedef void (*filter_exit) (void); typedef void (*waypt_cb) (const waypoint *); typedef void (*route_hdr)(const route_head *); @@ -364,6 +365,7 @@ typedef struct filter_vecs { filter_init f_init; filter_process f_process; filter_deinit f_deinit; + filter_exit f_exit; arglist_t *args; } filter_vecs_t; @@ -389,6 +391,7 @@ filter_vecs_t * find_filter_vec(char *, char **); void free_filter_vec(filter_vecs_t *); void disp_filters(int version); void disp_filter_vecs(void); +void exit_filter_vecs(void); #ifndef DEBUG_MEM void *xcalloc(size_t nmemb, size_t size); diff --git a/gpsbabel/duplicate.c b/gpsbabel/duplicate.c index 7f11fac9b..afeed3603 100644 --- a/gpsbabel/duplicate.c +++ b/gpsbabel/duplicate.c @@ -257,5 +257,6 @@ filter_vecs_t duplicate_vecs = { duplicate_init, duplicate_process, duplicate_deinit, + NULL, dup_args }; diff --git a/gpsbabel/filter_vecs.c b/gpsbabel/filter_vecs.c index 772d7adf5..1ff52928d 100644 --- a/gpsbabel/filter_vecs.c +++ b/gpsbabel/filter_vecs.c @@ -36,6 +36,7 @@ extern filter_vecs_t polygon_vecs; extern filter_vecs_t routesimple_vecs; extern filter_vecs_t reverse_route_vecs; extern filter_vecs_t sort_vecs; +extern filter_vecs_t stackfilt_vecs; static fl_vecs_t filter_vec_list[] = { @@ -79,6 +80,11 @@ fl_vecs_t filter_vec_list[] = { "sort", "Rearrange waypoints by resorting", }, + { + &stackfilt_vecs, + "stack", + "Save and restore waypoint lists" + }, { NULL, NULL, @@ -131,6 +137,19 @@ free_filter_vec( filter_vecs_t *fvec ) } } +void +exit_filter_vecs( void ) +{ + fl_vecs_t *vec = filter_vec_list; + while ( vec->vec ) { + if ( vec->vec->f_exit ) { + (vec->vec->f_exit)(); + } + vec++; + } +} + + /* * Display the available formats in a format that's easy for humans to * parse for help on available command line options. diff --git a/gpsbabel/main.c b/gpsbabel/main.c index 576bd673c..d0a1b27ad 100644 --- a/gpsbabel/main.c +++ b/gpsbabel/main.c @@ -290,6 +290,7 @@ main(int argc, char *argv[]) waypt_flush_all(); route_flush_all(); + exit_filter_vecs(); #ifdef DEBUG_MEM debug_mem_close(); diff --git a/gpsbabel/polygon.c b/gpsbabel/polygon.c index 4d9e20752..fd7850c6a 100644 --- a/gpsbabel/polygon.c +++ b/gpsbabel/polygon.c @@ -293,5 +293,6 @@ filter_vecs_t polygon_vecs = { polygon_init, polygon_process, polygon_deinit, + NULL, polygon_args }; diff --git a/gpsbabel/position.c b/gpsbabel/position.c index 3aa8b5fef..b7d6e3dca 100644 --- a/gpsbabel/position.c +++ b/gpsbabel/position.c @@ -357,6 +357,7 @@ filter_vecs_t position_vecs = { position_init, position_process, position_deinit, + NULL, position_args }; @@ -364,5 +365,6 @@ filter_vecs_t radius_vecs = { radius_init, radius_process, radius_deinit, + NULL, radius_args }; diff --git a/gpsbabel/queue.h b/gpsbabel/queue.h index 7392ce6d2..2cbb72748 100644 --- a/gpsbabel/queue.h +++ b/gpsbabel/queue.h @@ -32,6 +32,12 @@ queue * dequeue(queue *element); #define QUEUE_NEXT(element) (element)->next #define QUEUE_LAST(head) (head)->prev #define QUEUE_EMPTY (head)->next == head +#define QUEUE_MOVE(newhead,oldhead) \ + (newhead)->next = (oldhead)->next; \ + (newhead)->prev = (oldhead)->prev; \ + (newhead)->next->prev = (newhead); \ + (newhead)->prev->next = (newhead); \ + (oldhead)->next = (oldhead)->prev = (oldhead) #define ENQUEUE_TAIL(listhead, element) \ enqueue(element, (listhead)->prev) diff --git a/gpsbabel/reverse_route.c b/gpsbabel/reverse_route.c index b9d882435..336537251 100644 --- a/gpsbabel/reverse_route.c +++ b/gpsbabel/reverse_route.c @@ -62,5 +62,6 @@ filter_vecs_t reverse_route_vecs = { reverse_route_init, reverse_route_process, reverse_route_deinit, + NULL, reverse_route_args }; diff --git a/gpsbabel/smplrout.c b/gpsbabel/smplrout.c index f20592149..3c3b0a17b 100644 --- a/gpsbabel/smplrout.c +++ b/gpsbabel/smplrout.c @@ -246,5 +246,6 @@ filter_vecs_t routesimple_vecs = { routesimple_init, routesimple_process, routesimple_deinit, + NULL, routesimple_args }; diff --git a/gpsbabel/sort.c b/gpsbabel/sort.c index 9a9a6b345..c773e65eb 100644 --- a/gpsbabel/sort.c +++ b/gpsbabel/sort.c @@ -100,5 +100,6 @@ filter_vecs_t sort_vecs = { sort_init, sort_process, NULL, + NULL, sort_args }; diff --git a/gpsbabel/stackfilter.c b/gpsbabel/stackfilter.c new file mode 100644 index 000000000..df6dbc244 --- /dev/null +++ b/gpsbabel/stackfilter.c @@ -0,0 +1,177 @@ +/* + Stack filter + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ +#include +#include "defs.h" + +#define MYNAME "Stack filter" + +extern queue waypt_head; + +static char *opt_push = NULL; +static char *opt_copy = NULL; +static char *opt_pop = NULL; +static char *opt_append = NULL; +static char *opt_discard = NULL; +static char *opt_replace = NULL; +static char *opt_swap = NULL; +static char *opt_depth = NULL; +static int swapdepth = 0; + +static +arglist_t stackfilt_args[] = { + {"push", &opt_push, "Push waypoint list onto stack", ARGTYPE_BOOL}, + {"copy", &opt_copy, "Copy waypoint list when pushing", ARGTYPE_BOOL}, + {"pop", &opt_pop, "Pop waypoint list from stack", ARGTYPE_BOOL}, + {"append", &opt_append, "Append list when popping", ARGTYPE_BOOL}, + {"discard", &opt_discard, "Discard top of stack when popping", ARGTYPE_BOOL}, + {"replace", &opt_replace, "Replace list with top of stack (default)", ARGTYPE_BOOL}, + {"swap", &opt_swap, "Swap waypoint list with element of stack", ARGTYPE_BOOL}, + {"depth", &opt_depth, "Element to use in swap operation", ARGTYPE_INT}, + {0, 0, 0, 0} +}; + +struct stack_elt { + queue waypts; + struct stack_elt *next; +} *stack = NULL; + + +void +stackfilt_process(void) +{ + struct stack_elt *tmp_elt = NULL; + queue *elem = NULL; + queue *tmp = NULL; + queue tmp_queue; + waypoint *wpt_tmp; + + if ( opt_push ) { + tmp_elt = (struct stack_elt *)xmalloc(sizeof(struct stack_elt)); + QUEUE_MOVE(&(tmp_elt->waypts), &waypt_head); + tmp_elt->next = stack; + stack = tmp_elt; + if ( opt_copy ) { + QUEUE_FOR_EACH( &(stack->waypts), elem, tmp ) { + waypt_add( waypt_dupe((waypoint *)elem)); + } + } + } + else if ( opt_pop ) { + tmp_elt = stack; + if ( !tmp_elt ) { + fatal( MYNAME ": stack empty\n"); + } + if ( opt_append ) { + QUEUE_FOR_EACH( &(stack->waypts), elem, tmp ) { + waypt_add( (waypoint *)elem); + } + } + else if ( opt_discard ) { + waypt_flush( &(stack->waypts) ); + } + else { + waypt_flush( &waypt_head ); + QUEUE_MOVE(&(waypt_head), &(stack->waypts) ); + } + stack = tmp_elt->next; + xfree( tmp_elt ); + } + else if ( opt_swap ) { + tmp_elt = stack; + while ( swapdepth > 1 ) { + if ( !tmp_elt->next ) { + fatal (MYNAME ": swap with nonexistent element\n"); + } + tmp_elt = tmp_elt->next; + swapdepth--; + } + QUEUE_MOVE(&tmp_queue, &(tmp_elt->waypts) ); + QUEUE_MOVE(&(tmp_elt->waypts), &waypt_head ); + QUEUE_MOVE(&waypt_head, &tmp_queue ); + } +} + +void +stackfilt_init(const char *args) { + + int invalid = 0; + + if ( opt_depth ) { + swapdepth = atoi( opt_depth ); + } + if ( opt_push ) { + if ( opt_pop || opt_append || opt_discard || opt_replace || + opt_swap || opt_depth ) { + invalid = 1; + } + } + else if ( opt_pop ) { + if ( opt_push || opt_copy || opt_swap || opt_depth ) { + invalid = 1; + } + if ( !!opt_append + !!opt_discard + !!opt_replace > 1 ) { + invalid = 1; + } + } + else if ( opt_swap ) { + if ( opt_push || opt_copy || opt_pop || opt_append || + opt_discard || opt_replace ) { + invalid = 1; + } + } + else { + invalid = 1; + } + + if ( invalid ) { + fatal (MYNAME ": invalid combination of options\n"); + } + +} + +void +stackfilt_deinit(void) { + swapdepth = 0; +} + +void +stackfilt_exit( void ) { + struct stack_elt *tmp_elt = NULL; + + if ( stack ) { + warning( MYNAME " Warning: leftover stack entries; " + "check command line for mistakes\n" ); + } + while ( stack ) { + waypt_flush( &(stack->waypts) ); + tmp_elt = stack; + stack = stack->next; + xfree(tmp_elt); + } +} + +filter_vecs_t stackfilt_vecs = { + stackfilt_init, + stackfilt_process, + stackfilt_deinit, + stackfilt_exit, + stackfilt_args +}; -- 2.30.2